﻿using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Windows.Forms;

namespace Marmat.Forms.Skin
{
    /// <summary>
    /// Skin按钮
    /// </summary>
    public partial class SkinButton : Control, IButtonControl, ISkinControl
    {
        /// <summary>
        /// 构建 button 的实例。
        /// </summary>
        public SkinButton()
        {
            InitializeComponent();
            SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            SetStyle(ControlStyles.Selectable, true);
            base.BackColor = Color.Transparent;
        }

        private void InitializeComponent()
        {
            this.SuspendLayout();
            // 
            // SkButton
            // 

            this.Name = "SkinButton";
            this.Size = new System.Drawing.Size(75, 23);
            this.ResumeLayout(false);
        }

        /// <summary>
        /// 鼠标是否按下
        /// </summary>
        private bool down_status = false;

        /// <summary>
        /// 鼠标是否在当前组件内。
        /// </summary>
        private bool enter_status = false;

        /// <summary>
        /// 引发 System.Windows.Forms.Control.Paint 事件。
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            //优化绘制质量
            e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;  //使绘图质量最高，即消除锯齿
            e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
            e.Graphics.CompositingQuality = CompositingQuality.HighQuality;

            var rect = new Rectangle(0, 0, this.Width - 1, this.Height - 1);
            // 计算背景色
            Color backColor = this.BackColor;
            Color borderColor = Configuration.DefaultTheme.BorderBase;
            Color foreColor = this.ForeColor;

            if (this.loading || !this.Enabled)
            {
                backColor = this.BackColor.Blend(Color.FromArgb((int)Math.Floor(256 * 0.5), Color.White));
            }
            else if (down_status)
            {
                backColor = this.BackColor.Blend(Color.FromArgb((int)Math.Floor(256 * 0.1), Color.Black));
                if (this.ThemeStyle == ThemeStyleEnum.Default)
                {
                    borderColor = Configuration.DefaultTheme.Primary.Blend(Color.FromArgb((int)Math.Floor(256 * 0.1), Color.Black));
                    foreColor = borderColor;
                    if (this.Plain)
                        backColor = Color.White;
                    else
                        backColor = Color.White.Blend(Color.FromArgb((int)Math.Floor(256 * 0.1), Configuration.DefaultTheme.Primary));
                }
                else
                    borderColor = backColor;
            }
            else if (enter_status || notifyDefault)
            {
                if (this.ThemeStyle == ThemeStyleEnum.Default)
                {
                    foreColor = Configuration.DefaultTheme.Primary;
                    if (this.Plain)
                        borderColor = Configuration.DefaultTheme.Primary;
                    else
                    {
                        backColor = Color.White.Blend(Color.FromArgb(Convert.ToInt32(256 * 0.1), Configuration.DefaultTheme.Primary));
                        borderColor = Color.White.Blend(Color.FromArgb((int)Math.Floor(256 * 0.3), Configuration.DefaultTheme.Primary));
                    }
                }
                else
                {
                    if (!this.Plain)
                        backColor = this.BackColor.Blend(Color.FromArgb((int)Math.Floor(256 * 0.2), Color.White));
                    borderColor = backColor;
                }
            }
            else
            {
                if (this.Plain)
                {
                    if (this.ThemeStyle != ThemeStyleEnum.Default)
                    {
                        foreColor = backColor;
                        borderColor = Color.White.Blend(Color.FromArgb((int)Math.Floor(256 * 0.4), backColor));
                        backColor = Color.White.Blend(Color.FromArgb((int)Math.Floor(256 * 0.1), backColor));
                    }
                }
                else
                {
                    if (this.ThemeStyle != ThemeStyleEnum.Default)
                    {
                        borderColor = backColor;
                    }
                }
            }

            //绘制按钮背景色
            GraphicsPath path = null;
            using (var bush = new SolidBrush(backColor))
            {
                if (this.Round)
                {
                    path = rect.GetRoundPath();
                }
                else if (this.Circle > 0)
                {
                    path = rect.GetRoundPath(this.Circle);
                }
                else
                    path = rect.GetRoundPath(0);
                e.Graphics.FillPath(bush, path);
            }
            if (borderColor != Color.Transparent)
            {
                using (Pen pen = new Pen(borderColor))
                    e.Graphics.DrawPath(pen, path);
            }

            path.Dispose();
            // 绘制图标及文本
            Image icon = this.Image;
            if (this.loading)
                icon = loadIcon;
            Size icon_size = default;
            Size text_size = default;
            if (icon != null)
                icon_size = new Size(Math.Min(icon.Width, this.Font.Height), Math.Min(icon.Height, this.Font.Height));
            if (!string.IsNullOrEmpty(this.Text))
                text_size = TextRenderer.MeasureText(this.Text, this.Font);

            int width = icon_size.Width + (icon_size != default && text_size != default ? 4 : 0) + text_size.Width;
            int left = rect.Left + (rect.Width - width) / 2;
            if (this.IconOnRight || this.loading)
            {
                draw_icon();
                draw_text();
            }
            else
            {
                draw_text();
                draw_icon();
            }

            // 绘制文本
            void draw_text()
            {
                if (!string.IsNullOrEmpty(this.Text))
                {
                    TextRenderer.DrawText(e.Graphics, this.Text, this.Font, new Rectangle(left, rect.Y, this.Width - left, rect.Height), foreColor, Color.Transparent, TextFormatFlags.VerticalCenter);
                    left += text_size.Width + 4;
                }
            }
            // 绘制图标
            void draw_icon()
            {
                if (icon != null)
                {
                    //e.Graphics.SmoothingMode = SmoothingMode.Default;
                    rect = new Rectangle(left, (this.Height - icon_size.Height) / 2, icon_size.Width, icon_size.Height);
                    e.Graphics.DrawImage(icon, rect, new Rectangle(0, 0, icon.Width, icon.Height), GraphicsUnit.Pixel);
                    left += icon_size.Width + 4;
                }
            }
        }

        protected override void OnMouseClick(MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                this.Select();
            }
            base.OnMouseClick(e);
        }

        /// <summary>
        /// 鼠标进入
        /// </summary>
        /// <param name="e"></param>
        protected override void OnMouseEnter(EventArgs e)
        {
            this.enter_status = true;
            this.Invalidate();
            base.OnMouseEnter(e);
        }

        /// <summary>
        /// 鼠标点击
        /// </summary>
        /// <param name="e"></param>
        protected override void OnMouseDown(MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                this.down_status = true;
                this.Invalidate();
            }
            base.OnMouseDown(e);
        }

        /// <summary>
        /// 鼠标离开
        /// </summary>
        /// <param name="e"></param>
        protected override void OnMouseLeave(EventArgs e)
        {
            this.enter_status = false;
            this.Invalidate();
            base.OnMouseLeave(e);
        }

        protected override void OnClick(EventArgs e)
        {
            base.OnClick(e);
            var form = this.FindForm();
            if (form is not null)
                form.DialogResult = this.DialogResult;
        }

        /// <summary>
        /// 鼠标抬起
        /// </summary>
        /// <param name="e"></param>
        protected override void OnMouseUp(MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                this.down_status = false;
                this.Invalidate();
            }
            base.OnMouseUp(e);
        }

        #region IButtonControl

        /// <summary>
        ///   获取或设置单击按钮时返回给父窗体的值。
        /// </summary>
        [Category("样式"), Description("获取或设置单击按钮时返回给父窗体的值。")]
        [DefaultValue(typeof(DialogResult), nameof(DialogResult.None))]
        public DialogResult DialogResult { get; set; } = DialogResult.None;

        /// <summary>
        /// 通知某个控件是默认按钮，以便相应调整其外观和行为。
        /// </summary>
        /// <param name="value">如果控件要用作默认按钮，值为 true；反之，值为 false。</param>
        public void NotifyDefault(bool value)
        {
            notifyDefault = value;
            this.Invalidate();
        }
        private bool notifyDefault;

        /// <summary>
        /// 为该控件生成 System.Windows.Forms.Control.Click 事件。
        /// </summary>
        public void PerformClick()
        {
            this.OnClick(EventArgs.Empty);
        }
        #endregion

    }
}
